<!--好友列表组件-->
<template>
    <div class="friend-list">
        <div class="friend-group" v-for="item in friendInfo" :key="item.char">
            <div class="index">{{item.char}}</div>
            <div :class="'info'+(curSelectFriendEmail === friend.user.email?' info-select':'')" v-for="friend in item.data" 
                :key="friend.user.email" @click="selectUser(friend)">
                <div class="avatar">
                    <el-image :src="friend.user.avatar" fit="cover" />
                    <!-- 离线遮罩层 -->
                    <div class="filter" v-show="!friend.user.online"></div>
                </div>
                <div class="remark"  @dblclick.stop="changeRemark" >
                    <input type="text" :value="friend.remark" disabled @blur="cancelRemark(friend, $event)" 
                        @keydown.enter="submitRemark(friend,$event)">
                </div>
                <div class="tool-item" v-if="isDefaultGroup" @click.stop="addFriendToGroup(friend)">
                    <el-tooltip  effect="dark" content="添加到分组" placement="bottom" :open-delay="500">
                        <i class="el-icon-plus icon"></i>
                    </el-tooltip>
                </div>
                <div class="tool-item" v-if="!isDefaultGroup" @click.stop="removeFriendToGroup(friend)">
                    <el-tooltip  effect="dark" content="从分组移除" placement="bottom" :open-delay="500">
                        <i class="el-icon-minus icon"></i>
                    </el-tooltip>
                </div>
                <div class="tool-item" @click.stop="delFriends(friend)"> 
                    <el-tooltip  effect="dark" content="删除好友" placement="bottom" :open-delay="500">
                        <i class="el-icon-close icon"></i>
                    </el-tooltip>
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts">
import { Vue, Component,Prop } from 'vue-property-decorator'
import * as pinyin4js from 'pinyin4js'
import axios from 'axios'

@Component({})
export default class FriendListCom extends Vue {

    $message:any
    $store:any

    // 当前选择的好友的邮箱信息
    public curSelectFriendEmail: string = ''

    // 当前分组内的好友列表，外部传入
    @Prop({type: Array, required:true})
    private friendList:any[] | any

    // 当前的所有分组信息
    @Prop({type:  Array, required:true})
    private groupList:any[]|any

    // 当前分组的组名
    @Prop({type:String, required:true})
    private name:string|any

    // 是否显示弹窗
    public showDialog:boolean = false

    // 是否是默认分组
    get isDefaultGroup(){
        return this.name.startsWith('_')
    }

    // 选择指定用户
    public selectUser(friend:any){
        this.curSelectFriendEmail = friend.user.email;
        this.$emit('selectFriend', friend)
    }

    // 修改好友备注
    public changeRemark(e:MouseEvent){
        const input = e.target as HTMLInputElement
        input.disabled = false
    }

    // 提交修改备注
    public submitRemark(friend:any, e:KeyboardEvent){
        const input = e.target as HTMLInputElement
        axios.post(`/api/v1/friend/remark?email=${friend.user.email}&remark=${input.value}`)
            .then(res=>{
                if(res.data.code===200){
                    this.$message.success('更新备注成功!')
                    friend.remark = res.data.data
                    input.blur()
                }else{
                    this.$message.error(res.data.msg)
                }
            })
            .catch(err=>{
                this.$message.error("更新备注失败:" + err)
                input.blur()
            })
    }

    // 取消修改备注
    public cancelRemark(friend:any, e:FocusEvent){
        const input = e.target as HTMLInputElement
        input.value = friend.remark
        input.disabled = true
    }

    // 将好友添加到指定分组
    public addFriendToGroup(friend:any){
        this.$prompt('请输入要加入的分组名称',"提示",{
            inputValidator: (input)=>{
                if(this.groupList.findIndex((g:any)=>g.name===input) < 0){
                    return "您未有该分组"
                }
                return true
            }
        }).then(res=>{
            const groupName = (res as any).value;
            axios.post(`/api/v1/friend/group/add/${groupName}/${friend.user.email}`)
                .then(res=>{
                    if(res.data.code===200){
                        const email = res.data.data
                        // 加入到当前分组中
                        this.groupList.find((g:any)=>g.name===groupName)?.targetUserEmails.push(email)
                        this.$message.success('加入分组成功!')
                    }else{
                        this.$message.error(res.data.msg)
                    }
                })
                .catch(err=>{
                    this.$message.error('加入分组失败:' + err)
                })
        }).catch(err=>{})
    }

    // 将好友从指定分组中移除
    public removeFriendToGroup(friend:any){
        const email = friend.user.email;
        this.$confirm(`您确定要把"${friend.remark}"从"${this.name}"组中移除吗?`,"警告",{type: 'warning'})
            .then(()=>{
                axios.post(`/api/v1/friend/group/remove/${this.name}/${email}`)
                    .then(res=>{
                        if(res.data.code===200){
                            const group = this.groupList.find((g:any)=>g.name===this.name)
                            if(typeof group !== 'undefined' ){
                                const index = group.targetUserEmails.findIndex((e:string)=>e===email)
                                if(index >= 0){
                                    group.targetUserEmails.splice(index, 1)
                                }
                            }
                            this.$message.success('移出分组成功!')
                        }else{
                            this.$message.error(res.data.msg)
                        }
                    })
                    .catch(err=>{
                        this.$message.error('移出分组失败:' + err)
                    })
            })
            .catch(err=>{})

    }


    // 解除好友关系
    public delFriends(friend:any){
        this.$confirm(`您确定要解除与"${friend.remark}"的好友关系吗?`,"警告",{type: 'warning'})
            .then(()=>{
                axios.post('/api/v1/friend/del/' + friend.user.email)
                    .then(res=>{
                        if(res.data.code === 200){
                            this.$message.success("好友关系解除成功")
                            this.releaseFriendSuccess(friend.user.email)
                        }else{
                            this.$message.error(res.data.msg)
                        }
                    })
                    .catch(err=>{
                        this.$message.error("解除关系失败:" + err)
                    })
            })
            .catch(()=>{})
    }

    // 成功解除好友关系的回调
    private releaseFriendSuccess(email:string){
        // 从最近联系列表中删除
        const recentMsgList:any[] = this.$store.state.recentMsgList
        let index = recentMsgList.findIndex(msg=> msg.showUser.email===email)
        if(index >= 0){
            recentMsgList.splice(index,1)
        }
        // 从好友列表中删除
        const friends:any[] = this.$store.state.friends
        index = friends.findIndex(f=>f.user.email===email)
        if(index >= 0){
            friends.splice(index,1)
        }
    }


    // 获取按首字母分组后了的列表
    get friendInfo(){
        const friends:any[] = this.friendList
        // 过滤后的朋友列表{char:'A',data:[friend]}
        const friendInfoList:any[] = []
        // 其他非字母开头的信息
        const otherInfo:any = {char: '#', data: []}
        friends.forEach(firend=>{
            const pinyin:string = pinyin4js.getShortPinyin(firend.remark)[0]
            const firstChar = pinyin.charAt(0).toUpperCase()
            // 过滤列表中是否有该项首字母开头的数据
            let isFound:boolean = false
            for(let i=0; i<friendInfoList.length;i++){
                const item = friendInfoList[i]
                // 非字母开头的加入'#'组中
                if(firstChar.match(/^[A-Z]$/i) == null){
                    otherInfo.data.push(firend)
                    isFound = true
                    break
                }
                // 相同首字母则直接加入
                if(item.char === firstChar){
                    item.data.push(firend)
                    isFound = true
                    break
                }
                // 比其小则在当前位置插入
                if(firstChar.charCodeAt(0) < item.char.charCodeAt(0)){
                    friendInfoList.splice(i, 0, {char: firstChar, data: [firend]})
                    isFound = true
                    break
                }
            }
            // 未找到则直接push
            if(!isFound){
                friendInfoList.push({char: firstChar, data: [firend]})
            }
        })
        // 如果其他类型开头的字母有值的话，push到最后
        if(otherInfo.data.length > 0){
            friendInfoList.push(otherInfo)
        }
        return friendInfoList;
    }

}
</script>

<style lang="less" scoped>
.friend-list{
    .friend-group{
        cursor: pointer;
        .index{
            color: #999999;
            padding: 0px 10px;
        }
        .info-select{
            background-color: #C7C6C5;
        }
        .info{
            display: flex;
            align-items: center;
            padding: 10px;
            &:hover:not(.info-select){
                background-color: #DEDBDA;
            }
            .avatar{
                width: 40px;
                height: 40px;
                border-radius: 4px;
                overflow: hidden;
                position: relative;
                .el-image{
                    width: 100%;
                    height: 100%;
                }
                .filter{
                    position: absolute;
                    width: 100%;
                    height: 100%;
                    left: 0;
                    top: 0;
                    background-color: rgba(0, 0, 0, 0.5);
                }
            }
            .remark{
                flex: 1;
                padding: 0 10px;
                font-size: 14px;
                color: #000;
                overflow: hidden;
                white-space: nowrap;
                text-overflow: ellipsis;
                input{
                    width: 98%;
                    outline: none;
                    padding: 2px;
                    border-width: 0px;
                    color: #000;
                }
                input[disabled]{
                    background-color: rgba(255, 255, 255, 0);
                }
            }
            &:hover{
                .tool-item{
                    display: block;
                    cursor: pointer;
                }
            }
            .tool-item{
                width: 20px;
                height: 20px;
                display: none;
                &:hover{
                    background-color: #999;
                }
                .icon{
                    width: 100%;
                    height: 100%;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }
            }
        }
    }
}
</style> 